package de.negativrekord.blockworld;

import com.riekoff.particlecubeworld.player.AGlobalTimingProgressListener;

import cc.creativecomputing.control.CCControl;
import cc.creativecomputing.events.CCMouseAdapter;
import cc.creativecomputing.graphics.CCGraphics;
import cc.creativecomputing.graphics.CCGraphics.CCPolygonMode;
import cc.creativecomputing.math.CCMath;
import cc.creativecomputing.math.CCVector3f;


public class KnnClassifier2 implements AGlobalTimingProgressListener{
	
	private CCVector3f _myCenters[];
	private int _myClassIndices[];
	private int _myDurations[];
	
	int _myLength;
	
	@CCControl(name="center speed", min=0f, max=1f)
	public float _cSpeed = 0f;
	
	@CCControl(name="set manual class")
	public boolean _cManual = false;
	
	@CCControl(name="class", min=0, max=9)
	public int _cClass = 0;
	
	int size = 0;
	int N_MAX;
	int N;
	float maxTime = 100f;
	float timePassed = 0f;
	int duration = 0;
	float _myAngle0 = 0f;
	float _myAngle1 = 0f;

	
	public KnnClassifier2 (int nClasses, int theSize) {
		size = theSize;
		N = 0;
		N_MAX = nClasses;
		_myCenters =  new CCVector3f[nClasses];
		_myClassIndices = new int[nClasses];
		recalc(N_MAX, 1000, 20, 0, 0);
	}
	
	public void initDurations (int nClasses) {
		_myDurations = new int[nClasses];
		for (int i=0; i<nClasses; i++) {
			_myDurations[i] = 1;
		}
	}
	
	public int getDuration() {
		return duration;
	}
	
	public void recalc (int usedClasses, int theLength, int nPoints, float theAngle0, float theAngle1) {
		
		N = nPoints;
		_myDurations = new int[nPoints];
		
		_myAngle0 = theAngle0;
		_myAngle1 = theAngle1;
		
		N = usedClasses;
		_myLength = theLength;
		
		for (int i=0; i<N; i++) {
			_myClassIndices[i] = i;
		}
	}
	
	private int getCurrentId (float theProgress) {
		return CCMath.min(CCMath.floor(theProgress * N), N - 1);
	}
	
	public void update (float theDeltaTime) {
		timePassed += theDeltaTime*_cSpeed;
	}
	
	private int _myCenterID = 0;
	int classSize = 6000;
	
	@Override
	public void progress (float theProgress) {
 		
		/*float sum = 0f;
		int cl = -1;
		int ii=0;
		for (int i=0; i < _myClassDurations.length; i++) {
			if (ii>=_myClassDurations.length) break;
			cl = _myClassDurations[ii];
			float r = sum*classSize-theProgress*duration*classSize;
			_myCenters[cl] = new CCVector3f (r*CCMath.sin(_myAngle0), 0, r*CCMath.cos(_myAngle0));
			sum += _myDurations[cl];
			ii += _myDurations[cl];
		}
		*/
		
		for (int i=0; i<N; i++) {
			float r = i*classSize-theProgress*classSize*N;
			_myCenters[i] = new CCVector3f (r*CCMath.sin(_myAngle0), 0, r*CCMath.cos(_myAngle0));
		}
		
		_myCenterID = getCurrentId (theProgress);
	}

	public CCVector3f[] centers0() {
		return _myCenters;
	}
	
	public int[] classIndices() {
		if (!_cManual) {
			return _myClassIndices;
		}
		else {
			int[] ret = new int[N];
			for (int i=0; i<N; i++) {
				ret[i] = _cClass;
			}
			return ret;
		}
	}
	
	public void draw (CCGraphics g) {
		
		g.pushAttribute();
		g.polygonMode(CCPolygonMode.LINE);
		g.color(1f,0,0);
		for (int i = 0; i < N;i++) {
			CCVector3f c =  _myCenters[i];
			g.pushMatrix();
			g.translate(c);
			g.sphere(100);

			g.popMatrix();
		}
		g.popAttribute();
	}

	public CCVector3f center(int theI) {
		return centers0()[theI];
	}

	public int centerID(){
		return _myCenterID;
	}
	
	@Override
	public void onRestart() {
		
	}
	
	public static int sum (int[] arr) {
		int ret = 0;
		for (float f: arr) {
			ret += f;
		}
		return ret;
	}
}
